home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / boxOp.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  6KB  |  221 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include "xpaint.h"
  18. #include "misc.h"
  19. #include "Paint.h"
  20.  
  21. typedef struct {
  22.     int    rx, ry;
  23.     int    startX, startY, endX, endY;
  24.     int    drawn;
  25.     Boolean    type;        /* Is is a rectangle or square? */
  26.     Boolean    fill;        /* Filled rectangle? */
  27.     Boolean    swap;
  28.     GC    gcx;
  29. } LocalInfo;
  30.  
  31. #define MKRECT(rect, sx, sy, ex, ey, typeFlag) do {            \
  32.     if (typeFlag == 1) {                        \
  33.         (rect)->width  = MAX(ABS(sx - ex),ABS(sy - ey));    \
  34.         (rect)->height = (rect)->width;                \
  35.         (rect)->x = (ex - sx < 0) ? sx - (rect)->width : sx;    \
  36.         (rect)->y = (ey - sy < 0) ? sy - (rect)->height : sy;    \
  37.     } else if (typeFlag == 2) {                    \
  38.         (rect)->width  = MAX(ABS(sx - ex),ABS(sy - ey));    \
  39.         (rect)->x      = sx - (rect)->width;            \
  40.         (rect)->y      = sy - (rect)->width;            \
  41.         (rect)->width  *= 2;                    \
  42.         (rect)->height = (rect)->width;                \
  43.     } else {                            \
  44.         (rect)->x      = MIN(sx, ex);                \
  45.         (rect)->y      = MIN(sy, ey);                \
  46.         (rect)->width  = MAX(sx, ex) - (rect)->x;        \
  47.         (rect)->height = MAX(sy, ey) - (rect)->y;        \
  48.     }                                \
  49. } while (0)
  50.  
  51. static int     boxStyle = 0;
  52.  
  53. static void    press(Widget w, LocalInfo *l, 
  54.                 XButtonEvent *event, OpInfo *info) 
  55. {
  56.     /*
  57.     **  Check to make sure all buttons are up, before doing this
  58.     */
  59.     if ((event->state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
  60.         return;
  61.  
  62.     l->swap = (event->button == Button2);
  63.  
  64.     l->rx   = info->x;
  65.     l->ry   = info->y;
  66.     l->endX = l->startX = event->x;
  67.     l->endY = l->startY = event->y;
  68.  
  69.     if (boxStyle == 1) 
  70.         l->type = 2;
  71.     else
  72.         l->type = (event->state & ShiftMask) ? 1 : 0;
  73.  
  74.     l->drawn = False;
  75. }
  76.  
  77. static void    motion(Widget w, LocalInfo *l, 
  78.                 XMotionEvent *event, OpInfo *info) 
  79. {
  80.     XRectangle    rect;
  81.  
  82.     if (l->drawn) {
  83.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  84.  
  85.         XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx, &rect,1);
  86.     }
  87.  
  88.     l->endX = event->x;
  89.     l->endY = event->y;
  90.  
  91.     /*
  92.     **  Really set this flag in the if statement
  93.     */
  94.     if (boxStyle == 1) 
  95.         l->type = 2;
  96.     else
  97.         l->type = (event->state & ShiftMask) ? 1 : 0;
  98.     if (l->drawn = (l->startX != l->endX || l->startY != l->endY)) {
  99.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  100.  
  101.         XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx,&rect, 1);
  102.     }
  103. }
  104.  
  105. static void    release(Widget w, LocalInfo *l, 
  106.                 XButtonEvent *event, OpInfo *info) 
  107. {
  108.     XRectangle    rect;
  109.     int        mask;
  110.     GC        fgc, lgc;
  111.  
  112.     /*
  113.     **  Check to make sure all buttons are up, before doing this
  114.     */
  115.     mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
  116.     switch (event->button) {
  117.     case Button1:    mask ^= Button1Mask; break;
  118.     case Button2:    mask ^= Button2Mask; break;
  119.     case Button3:    mask ^= Button3Mask; break;
  120.     case Button4:    mask ^= Button4Mask; break;
  121.     case Button5:    mask ^= Button5Mask; break;
  122.     }
  123.     if ((event->state & mask) != 0)
  124.         return;
  125.  
  126.     if (l->drawn && info->surface == opWindow) {
  127.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  128.  
  129.         XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx,&rect, 1);
  130.     }
  131.  
  132.     if (info->isFat && info->surface == opWindow)
  133.         return;
  134.  
  135.     MKRECT(&rect, l->rx, l->ry, event->x, event->y, l->type);
  136.  
  137.     UndoStart(w, info);
  138.  
  139.     if (l->swap) {
  140.         fgc = info->first_gc;
  141.         lgc = info->second_gc;
  142.     } else {
  143.         fgc = info->second_gc;
  144.         lgc = info->first_gc;
  145.     }
  146.  
  147.     if (l->fill)
  148.         XFillRectangles(XtDisplay(w), info->drawable, fgc, &rect, 1);
  149.     XDrawRectangles(XtDisplay(w), info->drawable, lgc, &rect, 1);
  150.  
  151.     if (info->surface == opPixmap) {
  152.         rect.width++;
  153.         rect.height++;
  154.         UndoSetRectangle(w, &rect);
  155.         PwUpdate(w, &rect, False);
  156.     }
  157. }
  158.  
  159. /*
  160. **  Public routines
  161. */
  162.  
  163. void *BoxAdd(Widget w)
  164. {
  165.     LocalInfo    *l = (LocalInfo *)XtMalloc(sizeof(LocalInfo));
  166.  
  167.     l->fill = False;
  168.     l->gcx  = GetGCX(w);
  169.  
  170.         XtVaSetValues(w, XtNcompress, True, NULL);
  171.  
  172.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  173.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  174.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  175.     SetCrossHairCursor(w);
  176.  
  177.     return l;
  178. }
  179. void BoxRemove(Widget w, LocalInfo *l)
  180. {
  181.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  182.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  183.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  184.  
  185.     XtFree((XtPointer)l);
  186. }
  187.  
  188. void *FBoxAdd(Widget w)
  189. {
  190.     LocalInfo    *l = (LocalInfo *)XtMalloc(sizeof(LocalInfo));
  191.  
  192.     l->fill = True;
  193.     l->gcx  = GetGCX(w);
  194.  
  195.         XtVaSetValues(w, XtNcompress, False, NULL);
  196.  
  197.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  198.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  199.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  200.     SetCrossHairCursor(w);
  201.     
  202.     return l;
  203. }
  204. void FBoxRemove(Widget w, LocalInfo *l)
  205. {
  206.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  207.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  208.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  209.  
  210.     XtFree((XtPointer)l);
  211. }
  212.  
  213. void BoxSetStyle(Boolean mode)
  214. {
  215.     boxStyle = mode ? 1 : 0;
  216. }
  217. Boolean BoxGetStyle(Boolean mode)
  218. {
  219.     return boxStyle == 0 ? False : True;
  220. }
  221.